package client;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.LinkedList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import common.Item;

public class View extends JFrame {
	private static final long serialVersionUID = 1030521141763328323L;
	private TraderImpl trader;
	private Client client;
	private boolean loggedIn;
	
	private JList list;
	private JLabel balanceLabel, loggedInLabel, itemsBoughtLabel, itemsSoldLabel;
	JButton loginButton;
	private JPanel contentPane;
	
	public View (){
		buildGUI();
		trader = null;
	}
	public void setClient(Client client){
		this.client = client;
	}
	
	public void setTrader(TraderImpl trader) throws RemoteException{
		this.trader = trader;
		setLoggedIn(trader.getTraderName());
	}
	
	public void removeTrader(){
		trader = null;
	}

	private void buildGUI() {
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter(){

			@Override
			public void windowClosing(WindowEvent arg0) {
				System.out.println("Logging out");
				try {
					client.logout();
				} catch (RemoteException | SQLException e) {
					System.out.println("Failed to logout");
				}
				System.exit(0);
			}


			
		});
		setBounds(100, 100, 400, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new GridLayout(0, 2, 0, 0));
		
		JPanel left = new JPanel();
		contentPane.add(left);
		left.setLayout(new GridLayout(9, 1, 0, 0));
		
		loggedInLabel = new JLabel("Not Logged In");
		loggedInLabel.setHorizontalAlignment(SwingConstants.LEFT);
		loggedInLabel.setFont(new Font("Tahoma", Font.BOLD, 12));
		left.add(loggedInLabel);
		
		loginButton = new JButton("Log in");
		loginButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (loggedIn){
					try {
						client.logout();
						setLoggedOut();
						
					} catch (SQLException e) {
						JOptionPane.showMessageDialog(null, e.getMessage());
					} catch (RemoteException e) {
						connectionError();
					}
				} else /* not logged in -> go ahead with login*/ {
					String traderName = null;
					String password = null;
					traderName = (String)JOptionPane.showInputDialog("What is your name?");
					password = (String)JOptionPane.showInputDialog("What is your password?");
					try {
						// Proceed if corred login details
						if(client.login(traderName, password)){
							setLoggedIn(traderName);
							updateListAndBalance();
						}
					} catch (MalformedURLException
							| NotBoundException | SQLException e) {
						JOptionPane.showMessageDialog(null, e.getMessage());
					} catch (RemoteException e) {
						connectionError();
					}
				}
			}
		});
		left.add(loginButton);
		
		JButton registerButton = new JButton("Register new trader");
		registerButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (loggedIn){
					try {
						client.logout();
						setLoggedOut();
					} catch (SQLException e) {
						JOptionPane.showMessageDialog(null, e.getMessage());
					} catch (RemoteException e) {
						connectionError();
					}
				}
				String traderName = null;
				String password = null;
				while (traderName == null || traderName.equalsIgnoreCase(""))
					traderName = (String)JOptionPane.showInputDialog("What is your name?");
				while (password == null || password.length() < 4)
					password = (String)JOptionPane.showInputDialog("Pick a password (more than 4 characters)");
				try {
					client.registerNewTrader(traderName, password);
					setLoggedIn(traderName);
					updateListAndBalance();
				} catch ( MalformedURLException
						| NotBoundException | SQLException e) {
					JOptionPane.showMessageDialog(null, e.getMessage());
				} catch (RemoteException e) {
					connectionError();
				}
			}
		});
		left.add(registerButton);
		
		JButton buyButton = new JButton("Buy");
		buyButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (loggedIn){
					if (list.getSelectedValue() instanceof ItemWrapper && list.getSelectedIndex() >= 0){
						ItemWrapper iw = (ItemWrapper)list.getSelectedValue();
						try {
							trader.buy((Item)iw.getItem());
							updateListAndBalance();
						} catch (SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (RemoteException e) {
							connectionError();
						}
					}
				}
			}
		});
		left.add(buyButton);
		
		JButton sellButton = new JButton("Sell");
		sellButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (loggedIn){
					String nameOfItem = null;
					while (nameOfItem == null || nameOfItem.equalsIgnoreCase(""))
						nameOfItem = (String)JOptionPane.showInputDialog("What is the name of the item you want to sell?");
					String priceOfItem = (String)JOptionPane.showInputDialog("Name your price...");
					try {
						Float f = Float.parseFloat(priceOfItem);
						trader.sell(nameOfItem, f);
					} catch (NumberFormatException e){
						JOptionPane.showMessageDialog(null, "Illegal number");
					} catch (RemoteException e) {
						connectionError();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
		left.add(sellButton);
		
		JButton wishButton = new JButton("Wish");
		wishButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				if (loggedIn){
					String nameOfItem = null;
					while (nameOfItem == null || nameOfItem.equalsIgnoreCase(""))
						nameOfItem = (String)JOptionPane.showInputDialog("What is the name of the item you are looking for?");
					String priceOfItem = (String)JOptionPane.showInputDialog("Name the highest acceptable price...");
					try {
						Float f = Float.parseFloat(priceOfItem);
						try {
							trader.watch(nameOfItem, f);
						} catch (SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} catch (NumberFormatException e){
						JOptionPane.showMessageDialog(null, "Illegal number");
					}
				}
			}
		});
		left.add(wishButton);
		
		JButton updateButton = new JButton("Update");
		updateButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				try {
					updateListAndBalance();
				} catch (RemoteException e) {
					connectionError();
				}
			}
		});
		left.add(updateButton);
		
		balanceLabel = new JLabel("Balance:");
		balanceLabel.setHorizontalAlignment(SwingConstants.LEFT);
		balanceLabel.setFont(new Font("Tahoma", Font.BOLD, 12));
		left.add(balanceLabel);
		JPanel itemsCounterPanel = new JPanel();
		itemsCounterPanel.setLayout(new GridLayout(0, 2, 0, 0));
		itemsBoughtLabel = new JLabel("Bought: ");
		itemsBoughtLabel.setHorizontalAlignment(SwingConstants.LEFT);
		itemsBoughtLabel.setFont(new Font("Tahoma", Font.BOLD, 12));
		itemsSoldLabel = new JLabel("Sold: ");
		itemsSoldLabel.setHorizontalAlignment(SwingConstants.LEFT);
		itemsSoldLabel.setFont(new Font("Tahoma", Font.BOLD, 12));
		itemsCounterPanel.add(itemsBoughtLabel);
		itemsCounterPanel.add(itemsSoldLabel);
		left.add(itemsCounterPanel);
		
		
		JPanel right = new JPanel();
		contentPane.add(right);
		right.setLayout(new BorderLayout(0, 0));

		list = new JList();
        /*
		list.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                	//TODO evaluate this  list selection listener - prbbly not necessary?
                	//selectedItem = (Item)list.getSelectedValue();
                }
            }
        });
        */

        JScrollPane pane = new JScrollPane();
        pane.getViewport().add(list);
        right.add(pane);
		setContentPane(contentPane);
	}
	
	private void setLoggedIn(String name) throws RemoteException{
		loggedIn = true;
		loggedInLabel.setText("Logged in: " + name);
		loginButton.setText("Log out");
		updateListAndBalance();
	}
	
	protected void setLoggedOut(){
		loggedIn = false;
		loggedInLabel.setText("Not Logged In");
		loginButton.setText("Log in");
		balanceLabel.setText("Balance:");
		itemsBoughtLabel.setText("Bought: ");
		itemsSoldLabel.setText("Sold: ");
	}
	
	protected void updateListAndBalance()  throws RemoteException{
		if (loggedIn){
			
			LinkedList<Item> itemList;
			try {
				itemList = trader.updateItemsList();
				if (itemList != null){
					list.setListData(wrapItemList(itemList));
				}
				balanceLabel.setText("Balance: " + trader.getAccountBalance());
				itemsBoughtLabel.setText("Bought: " + trader.getItemsBought());
				itemsSoldLabel.setText("Sold: " + trader.getItemsSold());
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private ItemWrapper[] wrapItemList(LinkedList<Item> list){
		ItemWrapper[] wraps = new ItemWrapper[list.size()];
		for (int i = 0; i < list.size(); i++){
			try {
				wraps[i] = new ItemWrapper(list.get(i));
			} catch (RemoteException e) {
				connectionError();
			}
		}
		return wraps;
	}
	private void connectionError()
	{
		JOptionPane.showMessageDialog(null, "Failed communication with server. Shutting down...");	
		System.exit(0);
	}
}
